package com.sky.common.util.helper;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.sky.common.util.ClassesUtil;
import com.sky.common.util.LogFormat;

public class Jsons {
	
	private static Log log = LogFactory.getLog(Jsons.class);

	private static Map<String, Map<String, Class<?>>> typeTranscodeClassMap = new ConcurrentHashMap<String, Map<String, Class<?>>>();

	public static void loadClass(String type, Class<?> superClass, String prefix) {

		Set<Class<?>> classes = ClassesUtil.getClasses(superClass.getPackage().getName());

		Map<String, Class<?>> clazzMap = getClassMap(type);

		for (Class<?> clazz : classes) {

			boolean isClazz = superClass.isAssignableFrom(clazz);

			if (!isClazz) {

				continue;
			}
			// 判断不是superclass
			if (clazz.getName().equals(superClass.getName())) {

				continue;
			}
			// add it to map
			String simpleName = clazz.getSimpleName();
			// 前缀是对的
			if (simpleName.startsWith(prefix)) {

				if (simpleName.length() > prefix.length()) {

					String transcode = simpleName.substring(prefix.length());

					log.info(LogFormat.formatMsg("Jsons.loadClass", prefix, "add " + prefix + " class " + clazz.getName() + ",transcode "
							+ transcode));

					clazzMap.put(transcode, clazz);
				}
			}
		}

	}

	private static Map<String, Class<?>> getClassMap(String type) {

		Map<String, Class<?>> typeMap = typeTranscodeClassMap.get(type);

		if (typeMap == null) {

			typeMap = new ConcurrentHashMap<String, Class<?>>();
			typeTranscodeClassMap.put(type, typeMap);

		}

		return typeMap;
	}

	@SuppressWarnings("unchecked")
	public static <T> T parseObject(String type, String transcode, String jsonString) {

		Class<?> clazz = getTranscodeClass(type, transcode);

		if (clazz == null) {

			log.warn(LogFormat.formatMsg("Jsons.parseObject", transcode, "can't find this transcode class,return map"));
			return (T) JSON.parse(jsonString);
		}

		return (T) JSON.parseObject(jsonString, clazz);
	}

	public static <T> List<T> parseArray(String jsonString, Class<T> clazz) {

		if (jsonString == null || jsonString.isEmpty()) {

			return null;
		}

		return JSON.parseArray(jsonString, clazz);
	}

	public static <T> T parseObject(String jsonString, Class<T> clazz) {

		return JSON.parseObject(jsonString, clazz);
	}

	// 从指定的包下面找对应的class
	private static Class<?> getTranscodeClass(String type, String transcode) {

		Map<String, Class<?>> typeMap = typeTranscodeClassMap.get(type);

		if (typeMap == null || typeMap.isEmpty()) {

			return null;
		}

		return typeMap.get(transcode);
	}

	/**
	 * 格式化对象2 jsonString function:
	 * 
	 * @param object
	 * @return
	 * @since JDK 1.6
	 */
	public static String toJSONString(Object object) {

		return JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
	}
}
